//code from Dorando and Sboulema's MiniT+, modified by Hemiola SUN
// modified by onemen

window.addEventListener("load", TMP_miniT_init, false);

function TMP_miniT_init()
{
   if (typeof(tablib)=="undefined") return;
   window.removeEventListener("load", TMP_miniT_init, false);

   // don't load tabmix into undock sidebar opened by ezsidebar extension
   var wintype = window.document.documentElement.getAttribute("windowtype");
   if (wintype == "mozilla:sidebar") return;
  
   // init tabmix functions
   tablib.init();
   TM_init();
   flst.init();
   TMP_LastTab.init();
   TMP_TBP_init();
   tabxOnLoad();
   window.addEventListener("unload", TM_deinit, false);

   //this window open form duplicateInWindow or delayRestoreTab
   if (window.duplicat)
      NW_waitForSessionHistory();

   // dragging tab
   if (gBrowser.mStrip.hasAttribute("ondraggesture")) {
      gBrowser.mStrip.setAttribute("ondraggesture", "TMP_TabDragGesture(event);");
      gBrowser.mStrip.setAttribute("ondragover", "TMP_TabDragOver(event);");
      gBrowser.mStrip.setAttribute("ondragdrop", "TMP_TabDragDrop(event);");
      gBrowser.mStrip.setAttribute("ondragexit", "TMP_TabDragExit(event);");
   }
   else { // we are in 1.0.7
      gBrowser.mStrip.addEventListener("draggesture", TMP_TabDragGesture, true);
      gBrowser.mStrip.addEventListener("dragover", TMP_TabDragOver, true);
      gBrowser.mStrip.addEventListener("dragdrop", TMP_TabDragDrop, true);
      gBrowser.mStrip.addEventListener("dragexit", TMP_TabDragExit, true);
   }

   // check if we can use Firefox Dragmark
   if ("mTabDropIndicatorBar" in gBrowser) {
      gBrowser.mTabDropIndicatorBar.addEventListener('dragover', TMP_TabDragOver, true);
      gBrowser.mTabDropIndicatorBar.addEventListener('dragdrop', TMP_TabDragDrop, true);
      // always enable tab Drag & Drop in FF 1.5 and above
      gPref.setBoolPref("extensions.tabmix.enableTabDrag", true);
   }
   else // we are in 1.0.7
      gPref.setBoolPref("extensions.tabmix.useFirefoxDragmark", false);

   var stringBundle = document.getElementById("tmp-string-bundle");
   TabDNDObserver.draglink = stringBundle.getString("droplink.label")

/* don't add it for now
   // fix from bug 248612 add this to gBrowser
   // so we add this if the user is on Firefox befor the bug landed
   if (!gBrowser.mDragOverDelay) {
      gBrowser.mDragTime = 0;
      gBrowser.mDragOverDelay = 350;
   }
*/
   
}

///////////////////////////////////////////////////////////////////////////
//// Drag and Drop observers

function TMP_TabDragGesture(aEvent)
{
   nsDragAndDrop.startDrag(aEvent, TabDNDObserver);
   aEvent.stopPropagation();
}

function TMP_TabDragOver(aEvent)
{
   nsDragAndDrop.dragOver(aEvent, TabDNDObserver);
   aEvent.stopPropagation();
}

function TMP_TabDragDrop(aEvent)
{
   nsDragAndDrop.drop(aEvent, TabDNDObserver);
   aEvent.stopPropagation();
}

function TMP_TabDragExit(aEvent)
{
   nsDragAndDrop.dragExit(aEvent, TabDNDObserver);
   aEvent.stopPropagation();
}

var TabDNDObserver = {
  gBackupLabel: "",
  gMsg: null,
  draglink: "",
  lastTime: 0,

  onDragStart: function (event, transferData, action)
  {
   if (!gPrefService.getBoolPref("extensions.tabmix.enableTabDrag")) return;
   if(event.target.localName != "tab" || event.originalTarget.localName == "toolbarbutton") return;

   for ( var i = 0; i < gBrowser.mTabs.length; i++ )
      gBrowser.mTabs[i].setAttribute("showbutton","off");

   transferData.data = new TransferData();

   var URI = gBrowser.getBrowserForTab(event.target).currentURI;
   if (URI) {
      transferData.data.addDataForFlavour("text/x-moz-url", URI.spec + "\n" + event.target.label);
      transferData.data.addDataForFlavour("text/unicode", URI.spec);
      transferData.data.addDataForFlavour("text/html", '<a href="' + URI.spec + '">' + event.target.label + '</a>');
   } else {
      transferData.data.addDataForFlavour("text/unicode", "about:blank");
   }
  },

  getSupportedFlavours : function ()
  {
   var flavourSet = new FlavourSet();
   flavourSet.appendFlavour("text/x-moz-url");
   flavourSet.appendFlavour("text/unicode");
   flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
   return flavourSet;
  },

  canDrop: function (aEvent, aDragSession)
  {
   if (aDragSession.sourceNode &&
       aDragSession.sourceNode.parentNode == gBrowser.mTabContainer) {
       var sourceBo = aDragSession.sourceNode.boxObject;
       if (aEvent.screenX >= sourceBo.screenX &&
           aEvent.screenX <= (sourceBo.screenX +sourceBo.width) &&
           aEvent.screenY >= sourceBo.screenY &&
           aEvent.screenY <= (sourceBo.screenY +sourceBo.height))
         return false;
   }
   return true;
  },

  onDragOver: function (event, flavours, session)
  {
   if (!gPrefService.getBoolPref("extensions.tabmix.enableTabDrag")) session.canDrop = false;

   var isTabReorder = session.sourceNode && session.sourceNode.parentNode == gBrowser.mTabContainer;
   var newIndex = this.getNewIndex(event);
   var oldIndex = session.sourceNode && "_tPos" in session.sourceNode ? session.sourceNode._tPos : -1;
   var left_right; // 1:right, 0: left, -1: drop link on tab to replace tab 
   if (newIndex < gBrowser.mTabs.length)
      left_right = this.getLeft_Right(event, newIndex, oldIndex, isTabReorder);
   else {
      newIndex = !isTabReorder && gPrefService.getBoolPref("extensions.tabmix.openTabNext") ? gBrowser.mTabContainer.selectedIndex :
                  gBrowser.mTabs.length - 1;
      left_right = 1;
   }

   var replaceTab = false;
   if (left_right == -1) { // check if tab is lock
      replaceTab = true;
      var aTab = gBrowser.mTabs[newIndex];
      var isLocked = aTab.hasAttribute("locked") && aTab.getAttribute("locked");
      // don't allow to drop on lock tab unless the tab is blanck or the user press Ctrl/Meta Key
      if (!event.ctrlKey && !event.metaKey && isLocked) {
         if (!gBrowser.isBlankNotBusyTab(aTab))
            session.canDrop = false;
      }
   }

   if (isTabReorder && oldIndex == newIndex)
      session.canDrop = false;

   if (session.canDrop && !this.isValidTarget(event, session)) 
      return;

   // show Drag & Drop message
   if (!isTabReorder) {
      // no gNavigatorBundle.getString("droponnewtabbutton") in 1.0.7
      this.gMsg = event.originalTarget.id == "tabs-newbutton" && "mTabDropIndicatorBar" in gBrowser ? gNavigatorBundle.getString("droponnewtabbutton") : this.draglink;
      var statusTextFld = document.getElementById("statusbar-display");
      if (statusTextFld.label != this.gMsg) {
         if (this.gBackupLabel=="") this.gBackupLabel = statusTextFld.label;
         statusTextFld.label = this.gMsg;
      }
   }

   if(!session.canDrop) {
      this.clearDragmark();
      return;
   }

   var hideIndicator = false;
   var tabhbox = document.getElementById("scroll-tabs-frame");
   var index = newIndex+left_right-1;
   var newTime;
   if ( event.clientX <= tabhbox.boxObject.x &&
         !gBrowser.mTabContainer.hasAttribute("disableScrollTabsLeft") ) {
      newTime = new Date().getTime();
      if (newTime - this.lastTime > 100) {
         gBrowser.mTabContainer.tabsScroll(-1);
         this.lastTime = newTime;
      }
      hideIndicator = true;
   }
   else if( event.target.localName != "tab" &&
            event.clientX >= (tabhbox.boxObject.x + tabhbox.boxObject.width) &&
            !gBrowser.mTabContainer.hasAttribute("disableScrollTabsRight") ) {
      newTime = new Date().getTime();
      if (newTime - this.lastTime > 100) {
         gBrowser.mTabContainer.tabsScroll(1);
         this.lastTime = newTime;
      }
      hideIndicator = true;
   }
   //xxx check later if we need this
   else if (!isTabReorder && !replaceTab && event.target.localName != "tab") {
      // only drop if tab is visible
      var dropLinkonTabbar = gBrowser.mTabContainer.isTabVisible(newIndex) &&
            (event.target.localName == "tabs" || event.target == gBrowser.mTabDropIndicatorBar.firstChild );
      hideIndicator = !dropLinkonTabbar;
      session.canDrop = dropLinkonTabbar;
   }
   // xxx check later if we need this
   else if (index > 0 && !gBrowser.mTabContainer.isTabVisible(index) && 
         !gBrowser.mTabs[index].collapsed &&
         !gBrowser.mTabContainer.hasAttribute("disableScrollTabsRight")) {
      newTime = new Date().getTime();
      if (newTime - this.lastTime > 100) {
         gBrowser.mTabContainer.tabsScroll(1);
         this.lastTime = newTime;
      }
      hideIndicator = true;
   }

   if ( replaceTab || hideIndicator ) {
      this.clearDragmark();
      return;
   }

   this.setDragmark(newIndex, left_right);

/* don't add it for now
   // start fix from bug 248612
   if (!isTabReorder && event.target.localName == "tab") {
      if (!gBrowser.mDragTime)
         gBrowser.mDragTime = Date.now();
      if (Date.now() >= gBrowser.mDragTime + gBrowser.mDragOverDelay)
         gBrowser.mTabContainer.selectedItem = event.target;
      return;
   }
   // end fix from bug 248612
*/

  },

  onDrop: function (event, dropData, session)
  {
   this.clearDragmark();

   var isTabReorder = session.sourceNode && session.sourceNode.parentNode == gBrowser.mTabContainer;
   var newIndex = this.getNewIndex(event);
   var oldIndex = session.sourceNode && "_tPos" in session.sourceNode ? session.sourceNode._tPos : -1;
   var left_right;

   if (newIndex < gBrowser.mTabs.length)
      left_right = this.getLeft_Right(event, newIndex, oldIndex, isTabReorder);
   else {
      newIndex = !isTabReorder && gPrefService.getBoolPref("extensions.tabmix.openTabNext") ? gBrowser.mTabContainer.selectedIndex :
                  gBrowser.mTabs.length - 1;
      left_right = 1;
   }

   if (isTabReorder) {
      // ctrl key and drop to duplicate tab
      if ((event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey) {
         gBrowser.TMmoveTabTo(gBrowser.duplicateTab(session.sourceNode), newIndex + left_right);
         return;
      }

      try {
         var isTabFocused = document.commandDispatcher.focusedElement == gBrowser.mCurrentTab && gBrowser.mTabs[oldIndex] == gBrowser.mCurrentTab;
      } catch (e) {
         isTabFocused = false;
      }

      newIndex += left_right - (newIndex > oldIndex);
      gBrowser.TMmoveTabTo(gBrowser.mTabs[oldIndex], newIndex);
      // move focus to content after draging the selected tab
      if (isTabFocused)
         gBrowser.mCurrentBrowser.contentWindow.focus();

      gBrowser.mTabs[newIndex].collapsed = false;
      if ( gBrowser.mTabContainer.getAttribute("flowing") == "multibar" &&
            gBrowser.mTabContainer.getAttribute("multibar") == "scrollbar" &&
            oldIndex < gBrowser.mTabContainer.collapsedTabs )
         gBrowser.mTabs[gBrowser.mTabContainer.collapsedTabs-1].collapsed = true;
      gBrowser.mTabContainer.ensureTabIsVisible(newIndex);

      checkBeforeAndAfter();
   }
   else {
      var url = transferUtils.retrieveURLFromData(dropData.data, dropData.flavour.contentType);

      // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
      // Also disallow dropping javascript: or data: urls--bail out
      if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
         /^\s*(javascript|data):/.test(url))
         return;

      gBrowser.dragDropSecurityCheck(event, session, url);

      var bgLoad = true;
      try {
         bgLoad = gPrefService.getBoolPref("browser.tabs.loadInBackground");
      }
      catch (e) { }

      if (event.shiftKey)
         bgLoad = !bgLoad; // shift Key reverse the pref

      url = getShortcutOrURI(url);
      var aTab = null;
      if (left_right > -1) {
         try {
            aTab = gBrowser.addTab(url);
            gBrowser.TMmoveTabTo(aTab, newIndex + left_right);
         } catch(ex) {
            // Just ignore invalid urls
            return;
         }
      } else {
         // Load in an existing tab.
         aTab = event.target;
         try {
            gBrowser.getBrowserForTab(aTab).loadURI(url);
         } catch(ex) {
            // Just ignore invalid urls
            return;
         }
      }
      if (gBrowser.mCurrentTab != aTab)
        gBrowser.TMP_selectNewForegroundTab(aTab, bgLoad, url);
   }
  },

  onDragExit: function (event, session)
  {
   gBrowser.mDragTime = 0;
   this.isValidTarget(event, session);
  },

  isValidTarget: function (event, session)
  {
   if ( event.clientY <= gBrowser.mStrip.boxObject.y+1 ||
         event.clientX < gBrowser.mStrip.boxObject.x ||
         event.clientY >= gBrowser.mStrip.boxObject.y + gBrowser.mStrip.boxObject.height) {
      if (document.getElementById("statusbar-display").label == this.gMsg) {
         document.getElementById("statusbar-display").label = this.gBackupLabel;
         this.gBackupLabel="";
      }
      this.clearDragmark(event);
      session.canDrop = false;
      return false;
   }
   return true;
  },

  getNewIndex: function (event)
  {
   // start to chack after collapsedTabs
   // if X is less then the first tab return 0
   // check if the tab is visible... if not return gBrowser.mTabs.length
   // check if Y is below the tab.... if yes go to next row
   // in the row find the closest tab by X,
   // if no tab is match return gBrowser.mTabs.length
   var mX = event.clientX, mY = event.clientY; 
   var i, aTab, tabs = gBrowser.mTabContainer.childNodes;
   var collapsed = gBrowser.mTabContainer.collapsedTabs;
   if ( !gBrowser.mTabContainer.hasAttribute("multibar") ) {
      for (i = event.target.localName == "tab" ? event.target._tPos : collapsed; i < gBrowser.mTabs.length; i++)
         if (mX < tabs[i].boxObject.x + tabs[i].boxObject.width) 
            return i;
   }
   else {
      for (i = collapsed; i < tabs.length; i++) {
         if (!gBrowser.mTabContainer.isTabVisible(i))
            return tabs.length;
         aTab = tabs[i];
         if (mY >= aTab.baseY) {
            while (i < tabs.length - 1 && inSameRow(aTab, tabs[i+1]) )
               i++;
         }
         else if (mX < aTab.boxObject.x + aTab.boxObject.width )
            return i;
         else if (i == tabs.length - 1 || !inSameRow(aTab, tabs[i+1]) )
            return i;
      }
   }
   return tabs.length;
  },

  getLeft_Right: function (event, newIndex, oldIndex, isTabReorder)
  {
   var clientX = event.clientX;
   var left_right, aTab = gBrowser.mTabs[newIndex];
   if (isTabReorder) {
      left_right = ( clientX < aTab.boxObject.x + aTab.boxObject.width / 2 ) ? 0 : 1;
      var isCtrlKey = ((event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey);
      if (!isCtrlKey) {
         if (newIndex == oldIndex - 1) left_right = 0;
         else if (newIndex == oldIndex + 1) left_right = 1;
      }
   }
   else {
      left_right = (clientX < aTab.boxObject.x + aTab.boxObject.width / 4 ) ? 0 : 1;
      if (left_right == 1 && clientX < aTab.boxObject.x + aTab.boxObject.width * 3 / 4 )
         left_right = -1;
   }
   return left_right;
  },

  setDragmark: function (index, left_right)
  {
   var newIndex = index + left_right;
   if (gBrowser.hasAttribute("dragmarkindex") && gBrowser.getAttribute("dragmarkindex") == newIndex)
      return;

   this.clearDragmark();// clear old dragmark if one exist

   if (!gPrefService.getBoolPref("extensions.tabmix.useFirefoxDragmark")) {
      var sameRow = newIndex != 0 && newIndex != gBrowser.mTabs.length &&
            inSameRow(gBrowser.mTabs[newIndex-1], gBrowser.mTabs[newIndex]);
      if (sameRow || left_right==0)
         this.setDragmarkAttribute(gBrowser.mTabs[newIndex], "atLeft");
      if (sameRow || left_right==1)
         this.setDragmarkAttribute(gBrowser.mTabs[newIndex-1], "atRight");
   }
   else {
      // code for firefox indicator
      var ib = gBrowser.mTabDropIndicatorBar;
      var ind = ib.firstChild;
      ib.setAttribute("dragging", "true");
      var tabStripBoxObject = document.getElementById("scroll-tabs-frame").boxObject;
      var halfIndWidth = Math.floor((ind.boxObject.width + 1) / 2);
      var newMarginLeft;
      var minMarginLeft = tabStripBoxObject.x - halfIndWidth - ib.boxObject.x;
      var maxMarginLeft = Math.min((minMarginLeft + tabStripBoxObject.width),
                  (ib.boxObject.x + ib.boxObject.width - ind.boxObject.width));
      if (gTabbarPosition == 0)
         ib.setAttribute("dragging", "false");
      if ( left_right == 0 )
         newMarginLeft = gBrowser.mTabs[newIndex].boxObject.screenX -
                         gBrowser.boxObject.screenX - halfIndWidth;
      else
         newMarginLeft = gBrowser.mTabs[index].boxObject.screenX +
                         gBrowser.mTabs[index].boxObject.width -
                         gBrowser.boxObject.screenX - halfIndWidth;

      // ensure we never place the drop indicator beyond our limits
      if (newMarginLeft < minMarginLeft)
         newMarginLeft = minMarginLeft;
      else if (newMarginLeft > maxMarginLeft)
            newMarginLeft = maxMarginLeft;

      ind.style.marginLeft = newMarginLeft + 'px';

      if ( gTabbarPosition == 1) {
         ind.style.marginTop = gBrowser.mTabs[index].boxObject.screenY -
                               ib.boxObject.screenY + "px";
         ind.style.backgroundPosition = "50% 0%";
      } else {
         var offset = gFirefox2DefaultTheme ? -3 : 0;
         ind.style.marginBottom = gBrowser.mTabContainer.boxObject.screenY -
                                  gBrowser.mTabs[index].boxObject.screenY + offset + "px";
         ind.style.backgroundPosition = "50% 100%";
         ib.setAttribute("dragging", "true");
      }

   }

   gBrowser.setAttribute("dragmarkindex", newIndex);
  },

  clearDragmark: function ()
  {
   if (!gBrowser.hasAttribute("dragmarkindex")) 
      return;

   if (!gPrefService.getBoolPref("extensions.tabmix.useFirefoxDragmark")) {
      var index = gBrowser.getAttribute("dragmarkindex");
      if (index != gBrowser.mTabs.length && gBrowser.mTabs[index].hasAttribute("dragmark"))
         this.removetDragmarkAttribute(gBrowser.mTabs[index]);
      if (index != 0 && gBrowser.mTabs[index-1].hasAttribute("dragmark"))
         this.removetDragmarkAttribute(gBrowser.mTabs[index-1]);
   }
   else
      gBrowser.mTabDropIndicatorBar.setAttribute('dragging','false');

   gBrowser.removeAttribute("dragmarkindex");
  },

  removetDragmarkAttribute: function (tab)
  {
   tab.removeAttribute("dragmark");
   if (TMP_getBoolPref(tabxBranch, "flexTabs", false) &&
         TMP_getIntPref(tabxBranch, "maxWidth", 250) != TMP_getIntPref(tabxBranch, "minWidth", 30) &&
         tab.hasAttribute("width"))
      window.setTimeout( function () {tab.removeAttribute("width");}, 0);
  },

  setDragmarkAttribute: function (tab, markSide)
  {
   if (TMP_getBoolPref(tabxBranch, "flexTabs", false) &&
         TMP_getIntPref(tabxBranch, "maxWidth", 250) != TMP_getIntPref(tabxBranch, "minWidth", 30))
      tab.setAttribute("width", tab.boxObject.width);
   tab.setAttribute("dragmark", markSide);
  }

} // TabDNDObserver end

function TMP_goButtonClick(event)
{
   // if go-Button has oncommand attribute we are befor bug 279687 landed
   if (!event.target.hasAttribute('oncommand') && event.button == 0)
      handleURLBarCommand(event);
   else if(event.button == 1) {
      // when user middle-click on go-Button duplicate current tab
      // unless the user typed value into the address bar
      var postData = { };
      canonizeUrl(event, postData);
      var url = gURLBar.value;
      if (url == gBrowser.currentURI.spec)
         gBrowser.duplicateTab(gBrowser.mCurrentTab);
      else {
         gURLBar.value = gBrowser.currentURI.spec;
         gBrowser.userTypedValue = null;
         openUILink(url, event, false, false, true, postData.value);
      }
   }
}

function TM_BrowserHome()
{
   var homePage = gHomeButton.getHomePage();
   if (TMP_whereToOpen(false).inNew) {
      var urls = homePage.split("|");
      var firstTabAdded = gBrowser.addTab(urls[0]);
      var bgLoad = getBoolPref("browser.tabs.loadBookmarksInBackground", false);
      content.focus();
      gBrowser.TMP_selectNewForegroundTab(firstTabAdded, bgLoad, urls[0]);

      for (var i = 1; i < urls.length; ++i)
         gBrowser.addTab(urls[i]);
   } 
   else 
      loadOneOrMoreURIs(homePage);
}

var undocloseTabButtonObserver = {
  onDragOver: function(aEvent, aFlavour, aDragSession)
    {
      var aLocalName = aDragSession.sourceNode ? aDragSession.sourceNode.localName : null;
      if (aLocalName!="tab") {
         aDragSession.canDrop = false;
         return true;
      }
      var statusTextFld = document.getElementById("statusbar-display");
      var stringBundle = document.getElementById("tmp-string-bundle");
      statusTextFld.label = stringBundle.getString("droptoclose.label");
      aEvent.target.setAttribute("dragover", "true");
      return true;
    },
  onDragExit: function (aEvent, aDragSession)
    {
      var aLocalName = aDragSession.sourceNode ? aDragSession.sourceNode.localName : null;
      if (aLocalName!="tab") return;
      var statusTextFld = document.getElementById("statusbar-display");
      statusTextFld.label = "";
      aEvent.target.removeAttribute("dragover");
    },
  onDrop: function (aEvent, aXferData, aDragSession)
    {
      var aLocalName = aDragSession.sourceNode ? aDragSession.sourceNode.localName : null;
      if (aLocalName=="tab") gBrowser.removeTab(aDragSession.sourceNode);
    },
  getSupportedFlavours: function ()
    {
      var flavourSet = new FlavourSet();
      flavourSet.appendFlavour("text/x-moz-url");
      return flavourSet;
    }
}

const prefStringTMHistory = "extensions.tabmix.opentabfor.history";
const NC_NS_TM = "http://home.netscape.com/NC-rdf#";
const prefStringTMUseMiddleClick = "extensions.tabmix.middlecurrent";
const prefStringTMBookmark = "extensions.tabmix.opentabfor.bookmarks";
function isBookmarkletTM(aSelection, aDS)
{
    if (aSelection && (aSelection.length == 1)
        && ((aSelection.type[0] == "Bookmark") || (aSelection.type[0] == "ImmutableBookmark")))
    {
        var jsURL = /^ *javascript:/;
        return jsURL.test(BookmarksUtils.getProperty(aSelection.item[0], NC_NS_TM+"URL", aDS));
    }
    else
        return false;
}

function openInWebPanelTM(aSelection, aDS)
{
    if (aSelection && (aSelection.length == 1)
        && ((aSelection.type[0] == "Bookmark") || (aSelection.type[0] == "ImmutableBookmark")))
        return BMDS.GetTarget(aSelection.item[0], RDF.GetResource(NC_NS_TM + "WebPanel"), true);
    else
        return false;
}

function whereToOpenLinkTabmix(aEvent, prefString, aSelection, aDS)
{
    var w = getTopWin();
    if (!w)
      return "window";

    var browserTarget = aEvent ? whereToOpenLink(aEvent) : "current";

    var topBrowser = w.document.getElementById("content");
    var prefService = Components.classes['@mozilla.org/preferences-service;1']
                                .getService(Components.interfaces.nsIPrefService).getBranch(null);
    if ((prefService.getBoolPref(prefString) || topBrowser.mCurrentTab.hasAttribute("locked"))
        && !isBookmarkletTM(aSelection, aDS)
        && !openInWebPanelTM(aSelection, aDS)) {
        var _button = aEvent instanceof MouseEvent ? aEvent.button : 0;
        if (aEvent && prefService.getBoolPref(prefStringTMUseMiddleClick) && (_button == 1 || _button == 0 && (aEvent.ctrlKey || aEvent.metaKey)))
            browserTarget = "current";
        else
        {
            if ((browserTarget == "current")
                && (topBrowser.mCurrentBrowser.webProgress.isLoadingDocument
                    || (topBrowser.mCurrentBrowser.currentURI.spec != "about:blank")))
                browserTarget = "tab";
        }
    }

    return browserTarget;
}

function TMP_whereToOpen(pref, altKey)
{
   var aTab = gBrowser.mCurrentTab;
   var isBlankTab = gBrowser.isBlankNotBusyTab(aTab);
   var isLockTab = !isBlankTab && aTab.hasAttribute("locked");

   var openTabPref = typeof(pref) == "string" ? gPref.getBoolPref(pref) : pref;
   if (typeof(altKey) != "undefined") {
      // don't reuse balnk tab if the user press alt key when the pref is to open in current tab
      if (altKey && !openTabPref)
         isBlankTab = false;

      // see bug 315034 If search is set to open in a new tab, 
      // Alt+Enter should open the search result in the current tab
      // so here we reverse the pref if user press Alt key
      openTabPref = (altKey ^ openTabPref) == 1;
   }

   return { inNew: !isBlankTab && (isLockTab || openTabPref), lock: isLockTab };
}

// update context menu for bookmarks manager and sidebar
// for bookmarks/places, history, sage and more.....
function TMP_updateContextMenu(open, openInWindow, openInTab, pref) {
   // if all 3 was hidden ... probably "Open all in Tabs" is visible
   if (open.hidden && openInWindow.hidden && openInTab.hidden)
      return;

   var w = getTopWin();
   if (w) {
      var where = w.TMP_whereToOpen(pref);

      if (!openInWindow.hidden && w.gSingleWindowMode)
         openInWindow.hidden = true;
      else if (openInWindow.hasAttribute("default"))
         openInWindow.removeAttribute("default");

      TMP_setItem(openInTab, "default", where.inNew ? "true" : null);

      if (open.hidden != where.lock)
         open.hidden = where.lock;
      if (!open.hidden)
         TMP_setItem(open, "default", !where.inNew ? "true" : null);
   }
   else {
      open.hidden = true;
      openInTab.hidden = true;
      openInWindow.hidden = false;
      openInWindow.setAttribute("default", true);
   }
}

// Show/hide one item (specified via name or the item element itself).
function TMP_showItem ( itemOrId, show ) {
   var item = typeof(itemOrId) == "string" ? document.getElementById(itemOrId) : itemOrId;
   if (item) 
      item.hidden = !show;
}

function TMP_setItem(itemOrId, attrib, val) {
   var item = typeof(itemOrId) == "string" ? document.getElementById(itemOrId) : itemOrId;
   if (val == null)
      item.removeAttribute(attrib);
   else if (!item.hasAttribute(attrib) || item.getAttribute(attrib) != val);
      item.setAttribute(attrib, val);
}
